/*
 * Copyright 2008 Karel Klic.
 * This file is part of Oslavanský Bot.
 * 
 * Oslavanský Bot is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
package categorybot;

import java.util.regex.*;
import java.util.*;

/**
 * Definice jazyka ve wikislovniku.
 */
public class Language {

  String languageId;
  Pattern languagePattern;
  ArrayList<WordType> pairList = new ArrayList<WordType>();
  ArrayList<Pattern> ignoreRemoveList;
  
  /**
   * 
   * @param languageId
   * Napr. "cestina".
   * @param ignoreRemoveList 
   * If any of the provided patterns matches any part of the language
   * section of the text, the language will not include removal requests to
   * the result of solveWord call.
   */
  public Language(String languageId, ArrayList<Pattern> ignoreRemoveList) {
    this.languageId = languageId;
    this.ignoreRemoveList = ignoreRemoveList;
    languagePattern = PatternFactory.getHeader2Pattern(languageId);
  }

  public Language add(String typeId, String categoryId, String categoryIdForm) {
    CategoryList categoryList = new CategoryList(categoryId, categoryIdForm);
    pairList.add(new WordType(typeId, categoryList));
    return this;
  }
  
  public Language add(ArrayList<String> typeIdList, String categoryId, String categoryIdForm) {
    CategoryList categoryList = new CategoryList(categoryId, categoryIdForm);
    pairList.add(new WordType(typeIdList, categoryList));
    return this;
  }
  
  /**
   * 
   * @param text
   * @return
   * Vrati seznam zmen. Seznam je prazdny, pokud zadne zmeny nejsou potreba.
   */
  public ArrayList<SolveCategoryResult> solveWord(String text) {
    ArrayList<SolveCategoryResult> result = new ArrayList<SolveCategoryResult>();
    // check if it contains our language
    // if it does not, no problematic word.
    Matcher matcher = languagePattern.matcher(text);
    if (!matcher.find()) {
      return result;
    }
    int beginLimit = matcher.end();
    int endLimit = text.length();
    Matcher nextLanguage = PatternFactory.getHeader2Pattern().matcher(text);
    nextLanguage.region(beginLimit, endLimit);
    if (nextLanguage.find()) {
      endLimit = nextLanguage.start();
    }
    
    // Check every language construct type
    for (WordType pair : pairList) {
      result.addAll(pair.solveWord(text, beginLimit, endLimit));
    }
    
    // Check if the language text matches any of the ignoreRemoveList patterns.
    // If true, remove all the removal requests from the result.
    String languageTextPart = text.substring(beginLimit, endLimit);
    for (Pattern pattern : ignoreRemoveList) {
      if (pattern.matcher(languageTextPart).find()) {
        // Positive match. Remove all removal requests.
        for (int i = 0; i < result.size(); ++i) {
          if (result.get(i).getChangeType() == SolveCategoryResult.ChangeType.Remove)
            result.remove(i--);
        }
        break;
      }
    }
    
    return result;
  }
}
